﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
using System.Windows.Forms;
using SYcwpb.Models;

namespace SYcwpb.Helpers
{
    /// <summary>
    /// 通过设置轮换休息时间，午饭休息时间排交路。未完成。
    /// </summary>
    class GenerateCrossingRoad
    {
        //private WriteLog log = new WriteLog("TrainInfo.txt");

        private SqlDataLayer sqlHelper = new SqlDataLayer();

        public string lineID ;

        private string TableName;

        private int TableID;         

        private string FirstID;

        /// <summary>
        /// 该时刻表所有车次的信息，元素为Train对象，如果某车次已在交路中，将会在该集合中删除
        /// </summary>
        public ArrayList allTrainInfo = new ArrayList();

        /// <summary>
        /// 便乘到另一终点的车次，1号线为到黎明站，2号线为到三台子站
        /// </summary>
        public ArrayList bc_last_arr ;

        /// <summary>
        /// 便乘到第一个站点的车次，1号线为十三号街站，2号线为全运路站
        /// </summary>
        public ArrayList bc_first_arr ;

        /// <summary>
        /// 所有交路的集合
        /// </summary>
        public ArrayList crossingRoadCollections = new ArrayList();

        /// <summary>
        /// 早/白班交接班时间
        /// </summary>
        public int int_ChangeTime_ZB ;

        /// <summary>
        /// 白/夜班交接班时间
        /// </summary>
        public int int_ChangeTime_BB ;

        /// <summary>
        /// 午饭时间
        /// </summary>
        public int int_LunchTime ;

        /// <summary>
        /// 晚饭时间
        /// </summary>
        public int int_SuperTime;

        /// <summary>
        /// 正常轮换时休息时间
        /// </summary>
        public int restTime ;

        /// <summary>
        /// 吃饭休息时间
        /// </summary>
        public int mealRestTime;

        /// <summary>
        /// 交接班地点，1号线为启工街，2号线为青年大街
        /// </summary>
        public string ChangeStation = "10";

        /// <summary>
        /// 1号线下行到十三号街吃饭，方向为1；2号线上行到全运路吃饭，方向为2
        /// </summary>
        public int mealDirection = 1;

        /// <summary>
        /// 超过该阈值的车，属于下一个班组
        /// </summary>
        public int thresholdValue = 2 * 60 * 60;


        public GenerateCrossingRoad(CrossingRoadParameter parameters)
        {
            InitParameters(parameters);

            InitAllTrainInfo();

            AddBcRoadToCrossingRoadCollections();

            SortCrossingRoadCollection();

            Generate();
        }

        /// <summary>
        /// 初始化参数
        /// </summary>
        /// <param name="parameters"></param>
        private void InitParameters(CrossingRoadParameter parameters)
        {
            this.lineID = parameters.lineID;

            this.TableID = parameters.TableID;

            this.TableName = parameters.TableName ;

            this.FirstID = parameters.FirstID ;

            this.int_ChangeTime_ZB = parameters.int_ChangeTime_ZB;

            this.int_ChangeTime_BB = parameters.int_ChangeTime_BB ;

            this.int_LunchTime = parameters.int_LunchTime ;

            this.int_SuperTime = parameters.int_SuperTime ;

            this.restTime = parameters.restTime;

            this.mealRestTime = parameters.mealRestTime;

            this.bc_last_arr = parameters.bc_last_arr ;

            this.bc_first_arr = parameters.bc_first_arr ;

            this.mealDirection = Convert.ToInt32(lineID);
        }

        /// <summary>
        /// 初始化 ArrayList ：allTrainInfo 
        /// </summary>
        private void InitAllTrainInfo()
        {
            string sql_traininfo = "select distinct A.TrainID,A.LastID,B.TBegin,A.Arrive,B.TEnd, DID from [" + TableName
                + "] A left join TrainDetailInfo B on A.TrainID = B.TrainID  where A.Station = '10' and B.tableInfo_id = '" + TableID + "' order by TBegin";
            DataTable dt_traininfo = sqlHelper.SelectDt(sql_traininfo);
            if(null == dt_traininfo || dt_traininfo.Rows.Count < 1)
            {
                Console.WriteLine("初始化时刻表列车信息失败！");
                return;
            }

            for (int i = 0; i < dt_traininfo.Rows.Count; i++ )
            {
                Train train = new Train();
                train.TrainID = dt_traininfo.Rows[i]["TrainID"].ToString();
                train.LastID = dt_traininfo.Rows[i]["LastID"].ToString();

                train.BeginTime = Convert.ToInt32(dt_traininfo.Rows[i]["TBegin"]);
                train.TimeAtChangePoint = Convert.ToInt32(dt_traininfo.Rows[i]["Arrive"].ToString());
                train.EndTime = Convert.ToInt32(dt_traininfo.Rows[i]["TEnd"].ToString());

                train.DID = dt_traininfo.Rows[i]["DID"].ToString();
                train.Init();

                string trainLine = (i + 1).ToString() + "  " +  train.TrainID + "  " + GlobalVariables.FormatTime(train.BeginTime.ToString()) + "  " 
                    + GlobalVariables.FormatTime(train.TimeAtChangePoint.ToString()) + "  " + GlobalVariables.FormatTime(train.EndTime.ToString() );
                //log.WriteLine(trainLine);

                if (train.LastID == FirstID && train.BeginTime < int_ChangeTime_ZB) //判别该车是否为早班出库车
                {
                    train.IsFirstOut = true;
                    train.group = GroupType.Morning;
                    CrossingRoad road = new CrossingRoad();
                    road.Add(train);
                    crossingRoadCollections.Add(road);   //为该早班出库的车次新增一个交路
                }
                else
                {
                    allTrainInfo.Add(train);     //将车次加入剩余未入交路的集合
                }
                
            }
            //log.Close();
        }

        /// <summary>
        /// 添加便乘交路到交路集合,将下行便乘过去的第一个车次附上
        /// </summary>
        private void AddBcRoadToCrossingRoadCollections()
        {
            int count = crossingRoadCollections.Count;

            for (int i = 0; i < count; i++)
            {
                Train train = (crossingRoadCollections[i] as CrossingRoad).GetFirstTrain();
                if (train == null)
                    continue;
                if (bc_last_arr.Contains(train.TrainID))
                {
                    CrossingRoad road = new CrossingRoad();  //新增交路，并标识该交路为便乘的交路
                    road.is_bc_last = true;
                    road.Add(train);

                    //为便乘的交路找到它的下一个车次
                    Train next = GetTrainByTrainID(train.Getbc_last_Train());
                    if (null != next)
                    {
                        road.Add(next);
                        allTrainInfo.Remove(next);
                    }
                    crossingRoadCollections.Add(road);

                }
                else if (bc_first_arr.Contains(train.TrainID))  //上行便乘的第二个车次在Generate()函数中作处理
                {
                    CrossingRoad road = new CrossingRoad();  //新增交路，并标识该交路为便乘的交路
                    road.is_bc_first = true;
                    road.Add(train);

                    crossingRoadCollections.Add(road);
                }
            }
        }

        /// <summary>
        /// 将便乘的车次先放前面，让其先选接班车次
        /// </summary>
        private void SortCrossingRoadCollection()
        {
            ArrayList temp = new ArrayList();
            for(int i = 0; i < crossingRoadCollections.Count;)
            {
                CrossingRoad road = crossingRoadCollections[i] as CrossingRoad;
                if (road.is_bc_last || road.is_bc_first)
                {
                    temp.Add(road);
                    crossingRoadCollections.Remove(road);
                    continue;
                }
                i++;
            }
            for (int i = 0; i < crossingRoadCollections.Count;i ++ )
            {
                temp.Add(crossingRoadCollections[i] as CrossingRoad);
            }

            crossingRoadCollections.Clear();

            crossingRoadCollections = temp;
        }

        /// <summary>
        /// 将该车次从allTrainInfo中删除
        /// </summary>
        private void RemoveTrainFromAll(string trainID)
        {

        }

        private void Generate()
        {
            for (int i = 0; i < crossingRoadCollections.Count; i++)
            {
                CrossingRoad currentRoad = (CrossingRoad)crossingRoadCollections[i];
                AddTrainToCrossingRoad(ref currentRoad,true);
            }
            //剩余没选上的车次另外安排交路
            while(allTrainInfo.Count > 0)
            {
                Train train = allTrainInfo[0] as Train;  //第一个车
                CrossingRoad newRoad = new CrossingRoad();
                newRoad.Add(train);
                AddTrainToCrossingRoad(ref newRoad, false);

                crossingRoadCollections.Add(newRoad);

                allTrainInfo.Remove(train);

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="currentRoad"></param>
        /// <param name="normal">标识该交路是否为正常交路</param>
        private void AddTrainToCrossingRoad(ref CrossingRoad currentRoad,bool normal)
        {
            int index = currentRoad.Items.Count - 1;
            while (!currentRoad.is_end)
            {
                Train currentTrain = currentRoad.Items[index] as Train;
                SetGroup(ref currentTrain, ref currentRoad, index);

                if (currentTrain.IsLastTrip)
                {
                    currentRoad.is_end = true;
                    break;
                }
                //接下一个车的开始时间
                int start = currentTrain.EndTime + restTime;

                if (currentTrain.Direction == mealDirection)  //吃饭的方向
                {
                    if (currentTrain.EndTime > int_LunchTime && !currentRoad.is_lunch)  //午饭接车时间后休息时间
                    {
                        currentRoad.is_lunch = true;
                        currentRoad.LunchTrain = currentTrain.TrainID;
                        start = currentTrain.EndTime + mealRestTime;
                    }
                    else if (currentTrain.EndTime > int_SuperTime && !currentRoad.is_dinner)  // 晚饭接车时间后休息时间
                    {
                        currentRoad.is_dinner = true;
                        currentRoad.DinerTrain = currentTrain.TrainID;
                        start = currentTrain.EndTime + mealRestTime;
                    }
                }
                else if (currentRoad.is_bc_first && currentRoad.Items.Count < 2)   //上行便乘的第一个车处理
                {
                    start = currentTrain.BeginTime + restTime;
                }

                Train next = SelectTrainFromAll(start, currentTrain.Direction,currentRoad);
                if (null == next)
                {
                    currentRoad.is_end = true;
                    break;
                }

                currentRoad.Add(next);
                allTrainInfo.Remove(next);
                index++;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="start"></param>
        /// <param name="direction">当前车次的方向</param>
        /// <returns></returns>
        private Train SelectTrainFromAll(int start,int direction,CrossingRoad road)
        {
            Train result = null;
            int resultDirection = direction == 1 ? 2 : 1;   //返回车次应该的方向
            foreach (Train train in allTrainInfo)
            {
                //上行便乘的特殊处理
                if (road.is_bc_first && road.Items.Count < 2)  //只有第一个车做此特殊处理，所以小于2
                {
                    if (train.BeginTime >= start && train.Direction == direction)
                    {
                        result = train;
                        break;
                    }
                    continue;
                }
                else if (train.BeginTime >= start && train.Direction == resultDirection)
                {
                    result = train;     //或许这里讲符合条件的车次都放进一个集合，然后按条件筛选后，选出最合适的车次
                    break;
                }
            }
            return result;
        }


        private void SetLeftTrainGroup(ref Train train,ref CrossingRoad road)
        {
            if (train.TimeAtChangePoint < int_ChangeTime_ZB)
            {
                train.group = GroupType.Morning;
            }
            else if (train.TimeAtChangePoint < int_ChangeTime_BB)
            {
                train.group = GroupType.Day;
                road.is_changeToDay = true;
            }
            else
            {
                train.group = GroupType.Night;
                road.is_changeToNight = true;
            }
        }

        /// <summary>
        ///对于正常生成的交路： 设置当前车次属于哪个班组
        /// </summary>
        /// <param name="?"></param>
        private void SetGroup(ref Train currentTrain, ref CrossingRoad currentRoad,int index)
        {
            string trainID = currentTrain.TrainID;
            if (currentTrain.TimeAtChangePoint < int_ChangeTime_ZB)
            {
                currentTrain.group = GroupType.Morning;
            }
            else if (currentTrain.TimeAtChangePoint < int_ChangeTime_BB && !currentRoad.is_changeToDay)
            {
                if (currentTrain.IsLastTrip)
                    currentTrain.group = GroupType.Morning;
                else if (index == 0)                            //剩余交路时，第一个车的特殊处理
                {
                    currentTrain.group = GroupType.Day;
                    currentRoad.is_changeToDay = true;
                }
                else if (currentTrain.TimeAtChangePoint >= thresholdValue + int_ChangeTime_ZB)
                {
                    currentTrain.group = GroupType.Day;
                    currentRoad.is_changeToDay = true;
                }
                else{
                    currentTrain.group = GroupType.Morning_Day;
                    currentRoad.is_changeToDay = true;
                }
            }
            else if (currentTrain.TimeAtChangePoint < int_ChangeTime_BB && currentRoad.is_changeToDay)
            {
                currentTrain.group = GroupType.Day;
            }
            else if (currentTrain.TimeAtChangePoint >= int_ChangeTime_BB && !currentRoad.is_changeToNight)
            {
                if (currentTrain.IsLastTrip)
                    currentTrain.group = GroupType.Day;
                else if (index == 0)
                {
                    currentTrain.group = GroupType.Night;
                    currentRoad.is_changeToNight = true;
                }
                else if (currentTrain.TimeAtChangePoint >= thresholdValue + int_ChangeTime_BB)
                {
                    currentTrain.group = GroupType.Night;
                    currentRoad.is_changeToNight = true;
                }
                else{
                    currentTrain.group = GroupType.Day_Night;
                    currentRoad.is_changeToNight = true;
                }
            }
            else if (currentRoad.is_changeToNight)
            {
                currentTrain.group = GroupType.Night;
            }
            else
            {
                MessageBox.Show("找不到该车次所属班组！");
            }
        }


        /// <summary>
        /// 从allTrainInfo中返回TrainID的Train对象，找不到则返回空
        /// </summary>
        /// <param name="trainID"></param>
        /// <returns></returns>
        private Train GetTrainByTrainID(string trainID)
        {
            Train result = null;
            foreach (Train train in allTrainInfo)
            {
                if (train.TrainID == trainID)
                    result = train;
            }
            return result;
        }
    }

}
